package net.jiupinshi.controller.user;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import net.jiupinshi.common.PageResult;
import net.jiupinshi.common.Result;
import net.jiupinshi.customAnnotation.LoginAnnotation;
import net.jiupinshi.dto.ApplyInfoInitDTO;
import net.jiupinshi.dto.ExpenseApplyDTO;
import net.jiupinshi.dto.ToConfirmInitDTO;
import net.jiupinshi.dto.UserDTO;
import net.jiupinshi.entity.ExpenseApply;
import net.jiupinshi.entity.Store;
import net.jiupinshi.enums.BusinessEnum;
import net.jiupinshi.enums.BusinessEnum.ExpenseApplyStatusEnum;
import net.jiupinshi.service.goods.GoodsCategoryService;
import net.jiupinshi.service.store.StoreService;
import net.jiupinshi.service.user.ExpenseApplyService;
import net.jiupinshi.util.CodeUtil;
import net.jiupinshi.util.SessionUtil;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Despription: 报销业务
 * @Author: penghui.guo
 * @Date: 2018/10/5 20:45
 */
@RestController
@RequestMapping("expenseApply")
public class ExpenseApplyController {

    @Autowired
    StoreService storeService;
    @Autowired
    ExpenseApplyService expenseApplyService;
    @Autowired
    GoodsCategoryService goodsCategoryService;


    /**
     * 报销申请列表
     * @param request
     * @param storeId
     * @return
     */
    @LoginAnnotation
    @RequestMapping("confirmedList")
    public Result getConfirmList(HttpServletRequest request, String startDate, String endDate, Long storeId, Integer pageNum){
        Result<PageResult<List<ExpenseApplyDTO>>> result = new Result<>();
        UserDTO user = SessionUtil.getUser(request);
        Long roleId = user.getRoleId();
        if(roleId == BusinessEnum.RoleTypeEnum.STORE_ASSISTANT.code){
            result.setMsg("权限不足！");
            return result;
        }
        result = handlerConfirmList(pageNum, startDate, endDate, null, storeId, ExpenseApplyStatusEnum.AUDITED.code, null);
        List<ExpenseApplyDTO> list = result.getData().getT();
        for (ExpenseApplyDTO dto : list){
            if(user.getId().equals(dto.getApplyUserId())){
                dto.setCanAdd(true);
            }
        }
        return result;
    }

    /**
     * 待审核报销申请列表
     * @param request
     * @param applyUserId
     * @return
     */
    @LoginAnnotation
    @RequestMapping("toConfirmList")
    public Result getToConfirmList(HttpServletRequest request, String startDate, String endDate, Long applyUserId, Integer pageNum){
        Long userId = SessionUtil.getUserId(request);
        Result<PageResult<List<ExpenseApplyDTO>>> result = handlerConfirmList(pageNum, startDate, endDate, applyUserId, null, ExpenseApplyStatusEnum.AUDITING.code, userId);
        return result;
    }

    /**
     * 获取待审核店铺列表【待审核报销申请列表】
     * @param request
     * @return
     */
    @LoginAnnotation
    @RequestMapping("toConfirmUsers")
    public Result getToConfirmUsers(HttpServletRequest request){
        Result<ToConfirmInitDTO> result = new Result<>();
        ToConfirmInitDTO dto = new ToConfirmInitDTO();
        UserDTO user = SessionUtil.getUser(request);
        List<UserDTO> list = expenseApplyService.getApplyUsersByExpenseUid(user.getId());
        dto.setUserName(user.getName());
        Store store = storeService.getStoreByUid(user.getId());
        dto.setStoreName(store.getName());
        dto.setUserDTOList(list);
        result.setSuccess();
        result.setData(dto);
        return result;
    }

    /**
     * 申请报销初始化
     * @param request
     * @return
     */
    @LoginAnnotation
    @RequestMapping("applyInfoInit")
    public Result applyInfoInit(HttpServletRequest request){
        Result<ApplyInfoInitDTO> result = new Result();
        ApplyInfoInitDTO applyInfoInitDTO = new ApplyInfoInitDTO();
        UserDTO user = SessionUtil.getUser(request);
        applyInfoInitDTO.setCategoryDTOS(goodsCategoryService.getCategorys());
        applyInfoInitDTO.setUserName(user.getName());
        if(user.getRoleId() == BusinessEnum.RoleTypeEnum.STOER_MANAGER.code){
            // 店长需要计算待审核申请个数
            Integer count = expenseApplyService.getToConfirmCountByEUid(user.getId());
            applyInfoInitDTO.setToConfirmNum(count);
        }
        applyInfoInitDTO.setExpenseStoreList(storeService.getStores());
        result.setSuccess();
        result.setData(applyInfoInitDTO);
        return result;
    }

    /**
     * 申请报销
     * @param request
     * @param applyList
     * @return
     */
    @LoginAnnotation
    @RequestMapping("saveExpenseApply")
    public Result saveExpenseApply(HttpServletRequest request, String applyList){

        return addExpenseApply(request, null, applyList);
    }

    /**
     * 追加报销
     * @param parentId
     * @param applyList
     * @return
     */
    @LoginAnnotation
    @RequestMapping("addExpenseApply")
    public Result addExpenseApply(HttpServletRequest request, Long parentId, String applyList){
        Result result = new Result();
        UserDTO user = SessionUtil.getUser(request);
        List<ExpenseApply> expenseApplies = JSON.parseObject(applyList, new TypeReference<List<ExpenseApply>>(){});
        buildExpenseApplyData(expenseApplies, user, parentId);
        int i = expenseApplyService.insertExpenseApplys(expenseApplies);
        if(i > 0){
            result.setSuccess();
        }
        return result;
    }

    /**
     * 确认/驳回审核
     * @param ids
     * @param request
     * @return
     */
    @LoginAnnotation
    @RequestMapping("confirmAudit")
    public Result confirmAudit(String ids, HttpServletRequest request, Byte status){
        Result result = new Result();
        Long userId = SessionUtil.getUserId(request);
        int i = expenseApplyService.updateExpenseApplys(userId,status, ids);
        if(i > 0){
            result.setSuccess();
        }
        return result;
    }

    /**
     * 追加页面数据初始化
     * @param id
     * @param request
     * @return
     */
    @LoginAnnotation
    @RequestMapping("getExpenseApply")
    public Result getExpenseApply(Long id, HttpServletRequest request){
        Long userId = SessionUtil.getUserId(request);
        ExpenseApplyDTO expenseApply = expenseApplyService.getExpenseApplyByUid(id, userId);
        //List<ExpenseApply> list = expenseApplyService.getExpenseApplysByPid(userId, id);
        Map<String, Object> map = new HashMap<>(2);
        map.put("parent", expenseApply);
        //map.put("children", list);
        Result result = new Result();
        result.setSuccess();
        result.setData(map);
        return result;
    }

    /**
     * 申请历史
     * @param request
     * @param pageNum
     * @param status
     * @return
     */
    @LoginAnnotation
    @RequestMapping("apply/history")
    public Result applyHistory(HttpServletRequest request, Integer pageNum, Byte status){
        Long userId = SessionUtil.getUserId(request);
        return handlerHistoryList(pageNum, userId, null, status);
    }

    /**
     * 申请历史
     * @param request
     * @param pageNum
     * @param status
     * @return
     */
    @LoginAnnotation
    @RequestMapping("confirm/history")
    public Result history(HttpServletRequest request, Integer pageNum, Byte status){
        Long userId = SessionUtil.getUserId(request);
        return handlerHistoryList(pageNum, null, userId, status);
    }

    /**
     * 导出excel
     * @param response
     * @param storeId
     */
    @LoginAnnotation
    @RequestMapping("exportExcel")
    public void exportExcel(HttpServletResponse response, String startDate, String endDate, Long storeId){
        List<Map<String, Object>> list = expenseApplyService.getExpenseApplyList(startDate, endDate, storeId, ExpenseApplyStatusEnum.AUDITED.code);
        Context context = new Context();
        context.putVar("applyExpenses", list);
        try (OutputStream os = response.getOutputStream();
             InputStream is = new FileInputStream(ResourceUtils.getFile("classpath:confirm_model.xls"));){
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String("审核数据".getBytes(),"ISO8859-1")+".xls");
            JxlsHelper.getInstance().processTemplate(is, os, context);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void buildExpenseApplyData(List<ExpenseApply> expenseApplies, UserDTO user, Long parentId){
        Store store = null;
        if(parentId != null){
            store = expenseApplyService.getStoreByApplyExpenseId(parentId);
        }
        for(ExpenseApply expenseApply : expenseApplies){
            if(parentId == null){
                store = storeService.getStoreById(expenseApply.getExpenseStoreId());
            }
            expenseApply.setApplyUserName(user.getName());
            expenseApply.setApplyUserId(user.getId());
            expenseApply.setExpenseUserName(store.getUserName());
            expenseApply.setExpenseUserId(store.getUserId());
            expenseApply.setExpenseStoreId(store.getId());
            expenseApply.setExpenseStoreName(store.getName());
            expenseApply.setCode(CodeUtil.createExpenseApplyCode());
            expenseApply.setParentId(parentId);
        }
    }

    public Result handlerConfirmList(Integer pageNum, String startDate, String endDate, Long applyUserId, Long storeId, Byte status, Long expenseUserId){
        Result<PageResult<List<ExpenseApplyDTO>>> result = new Result<>();
        endDate = addOneDate(endDate);
        result.setSuccess();
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(pageNum);
        int pageSize = pageResult.getPageSize();
        int total = expenseApplyService.getExpenseApplysCount(startDate, endDate, applyUserId, storeId, status, expenseUserId);
        pageResult.setTotal(total);
        List<ExpenseApplyDTO> list = expenseApplyService.getExpenseApplys(startDate, endDate, applyUserId, storeId, status, expenseUserId, (pageNum-1)*pageSize, pageSize);
        pageResult.setT(list);
        result.setData(pageResult);
        return result;
    }

    public Result handlerHistoryList(Integer pageNum, Long applyUserId, Long expenseUserId, Byte status){
        Result<PageResult<List<ExpenseApplyDTO>>> result = new Result<>();
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(pageNum);
        pageNum = pageResult.getPageNum();
        status = status == 0 ? null : status;
        int count = pageResult.getPageSize();
        int total = expenseApplyService.getExpenseApplyCountByStatusUid(applyUserId, expenseUserId, status);
        List<ExpenseApplyDTO> list = expenseApplyService.getExpenseApplyByStatusUid(applyUserId, expenseUserId, status, (pageNum - 1) * count, count);
        pageResult.setTotal(total);
        pageResult.setT(list);
        result.setData(pageResult);
        result.setSuccess();
        return result;
    }

    /**
     * yyyy-MM-dd +1 天
     * @param date
     * @return
     */
    public String addOneDate(String date){
        if (!StringUtils.isEmpty(date)) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            try {
                calendar.setTime(simpleDateFormat.parse(date));
                calendar.add(Calendar.DATE, 1);
                date = simpleDateFormat.format(calendar.getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return date;
    }


    public static void main(String[] args) {
        List<HashMap> list = new ArrayList<>();
        HashMap map = new HashMap();
        map.put("content", "咖啡豆");
        map.put("amount", 200);
        map.put("number", 20);
        list.add(map);
        map = new HashMap();
        map.put("content", "小豆");
        map.put("amount", 100);
        map.put("number", 10);
        list.add(map);
        System.out.println(JSON.toJSONString(list));
        System.out.println(URLEncoder.encode(JSON.toJSONString(list)));
    }
}
